local ls = require("luasnip")
local s = ls.snippet
local t = ls.text_node
local i = ls.insert_node
local fmt = require("luasnip.extras.fmt").fmt

ls.add_snippets("dart", {
  -- Import Material
  s("imat", t([[import 'package:flutter/material.dart';

]])),

  -- BuildContext
  s("context", t("BuildContext context")),

  -- Function
  s("fn", fmt([[
void {}() {{
  {}
}}
]], {i(1, "func"), i(0)})),

  -- Async Function
  s("afn", fmt([[
Future<void> {}() async {{
  {}
}}
]], {i(1, "func"), i(0)})),

  -- Widget Function
  s("wfunc", fmt([[
Widget build{}() {{
  return {};
}}
]], {i(1, "Widget"), i(0, "Container()")})),

  -- Else
  s("el", t("} else {")),

  -- Else if
  s("elif", fmt("}} else if ({}) {{", {i(0)})),

  -- MaterialStateProperty.all
  s("msa", fmt("MaterialStateProperty.all({}),", {i(0)})),

  -- MaterialStateProperty.resolveWith
  s("msr", fmt([[
MaterialStateProperty.resolveWith<{}>((states) => states.contains(MaterialState.pressed) ? null : null),]], {i(1)})),

  -- Width and height
  s("wh", fmt([[
width: {},
height: {},]], {i(1), i(0)})),

  -- Infinity Width
  s("iwh", t("width: double.infinity,")),

  -- SizedBox with width and height
  s("swh", fmt([[SizedBox(width: {}, height: {}),{}]], {i(1), i(2), i(0)})),

  -- Positioned
  s("pos", fmt([[
Positioned(
  top: {},
  left: {},
  child: {},
),]], {i(1, "0"), i(2, "0"), i(3, "Container()")})),
  
  -- Class
  s("class", fmt([[
class {} {{
  {}
}}]], {
    i(1, "ClassName"),
    i(2, "// class body"),
  })),

  -- StatelessWidget
  s("stless", fmt([[
class {} extends StatelessWidget {{
  const {}({{Key? key}}) : super(key: key);

  @override
  Widget build(BuildContext context) {{
    return {};
  }}
}}]], {
    i(1, "WidgetName"),
    i(2, "WidgetName"),
    i(3, "Container()"),
  })),

  -- StatefulWidget
  s("stful", fmt([[
class {} extends StatefulWidget {{
  const {}({{Key? key}}) : super(key: key);

  @override
  _{}State createState() => _{}State();
}}

class _{}State extends State<{}> {{
  @override
  Widget build(BuildContext context) {{
    return {};
  }}
}}]], {
    i(1, "WidgetName"),
    i(2, "WidgetName"),
    i(3, "WidgetName"),
    i(4, "WidgetName"),
    i(5, "WidgetName"),
    i(6, "WidgetName"),
    i(7, "Container()"),
  })),

  -- Build method
  s("build", fmt([[
@override
Widget build(BuildContext context) {{
  return {};
}}]], {
    i(1, "Container()"),
  })),

  -- Constructor
  s("cons", fmt([[
const {}({{{}this.{}}});]], {
    i(1, "ClassName"),
    i(2, "required "),
    i(3, "property"),
  })),

  -- setState
  s("setst", fmt([[
setState(() {{
  {}
}});]], {
    i(1, "// state update"),
  })),

  -- initState
  s("initS", fmt([[
@override
void initState() {{
  super.initState();
  {}
}}]], {
    i(1, "// initialization"),
  })),

  -- dispose
  s("dis", fmt([[
@override
void dispose() {{
  {}
  super.dispose();
}}]], {
    i(1, "// cleanup"),
  })),

  -- Future function
  s("fut", fmt([[
Future<{}> {}() async {{
  {}
}}]], {
    i(1, "void"),
    i(2, "functionName"),
    i(3, "// async code"),
  })),

  -- Stream
  s("stream", fmt([[
Stream<{}> {}() async* {{
  {}
}}]], {
    i(1, "int"),
    i(2, "streamName"),
    i(3, "// stream code"),
  })),

  -- Try-catch
  s("try", fmt([[
try {{
  {}
}} catch (e) {{
  {}
}}]], {
    i(1, "// code"),
    i(2, "print(e)"),
  })),
})
